package com.gwnet.rider.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gwnet.common.enums.AmountTypeEnum;
import com.gwnet.common.enums.IOTypeEnum;
import com.gwnet.common.enums.OwnerTypeEnum;
import com.gwnet.common.enums.ShopWalletChangeReason;
import com.gwnet.common.util.Arith;
import com.gwnet.rider.domain.PlatformWalletLog;
import com.gwnet.rider.domain.RiderWallet;
import com.gwnet.rider.domain.bo.PlatformWalletLogPageBO;
import com.gwnet.rider.mapper.PlatformWalletLogMapper;
import com.gwnet.rider.mapper.RiderWalletMapper;
import com.gwnet.rider.service.PlatformWalletLogService;
import com.gwnet.shop.domain.OrderDelivery;
import com.gwnet.shop.domain.OrderInfo;
import com.gwnet.shop.domain.ShopWallet;
import com.gwnet.shop.mapper.OrderDeliveryMapper;
import com.gwnet.shop.mapper.OrderInfoMapper;
import com.gwnet.shop.mapper.ShopWalletMapper;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * <p>
 * 收支记录表 服务实现类
 * </p>
 *
 * @author WangLiang
 * @since 2024-08-06
 */
@Service
@AllArgsConstructor
public class PlatformWalletLogServiceImpl extends ServiceImpl<PlatformWalletLogMapper, PlatformWalletLog> implements PlatformWalletLogService {

    private final PlatformWalletLogMapper platformWalletLogMapper;
    private final RiderWalletMapper riderWalletMapper;
    private final ShopWalletMapper shopWalletMapper;
    private final OrderInfoMapper orderInfoMapper;
    private final OrderDeliveryMapper deliveryMapper;


    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    @Override
    public Boolean genWalletLog(OrderInfo orderInfo, OrderDelivery delivery) {

        // TODO 获取平台配置的 骑手抽成 和 商家抽成 的百分点
        // 计算骑手的钱 和 平台佣金，这里都先写死，后续通过读平台配置计算
        double riderCommissionRate =  0.1;
        // 平台从骑手抽出的佣金
        double platformRiderAmount = Arith.mul(orderInfo.getDeliverAmount(), riderCommissionRate);
        // 骑手实际得到的钱
        double riderGetAmount = Arith.sub(orderInfo.getDeliverAmount(), platformRiderAmount);

        // 骑手收支记录实体
        PlatformWalletLog riderLog = new PlatformWalletLog();
        riderLog.setOwnerId(delivery.getRiderId());
        riderLog.setOwnerType(OwnerTypeEnum.RIDER.code());
        riderLog.setOrderId(orderInfo.getOrderId());
        riderLog.setDevId(delivery.getId());
        riderLog.setIoType(IOTypeEnum.IN.code());
        riderLog.setAmountType(AmountTypeEnum.UNSETTLED_AMOUNT.code());
        riderLog.setChangeAmount(riderGetAmount);
        riderLog.setReason(ShopWalletChangeReason.PAY.value());
        // 商家优惠券/补贴 平台优惠券/补贴  后期增加的话需要加入
        riderLog.setUserAmount(orderInfo.getOrderAmount());
        riderLog.setPlatformCommission(platformRiderAmount);
        riderLog.setTotalAmount(orderInfo.getGoodsAmount());
        int riderCount = platformWalletLogMapper.insert(riderLog);



        // 计算商家的钱 和 平台佣金  totalPackageMoney(打包金额) + goodsAmount(商品金额)
        double shopCommissionRate =  0.1;
        double shopAmount = Arith.add(orderInfo.getTotalPackageMoney(), orderInfo.getGoodsAmount());
        // 平台从商家中抽出的佣金
        double platformShopAmount = Arith.mul(shopAmount, shopCommissionRate);
        // 商家实际得到的钱
        double shopGetAmount = Arith.sub(shopAmount, platformShopAmount);

        // 商家收支记录实体
        PlatformWalletLog shopLog = new PlatformWalletLog();
        shopLog.setOwnerId(orderInfo.getTenantId());
        shopLog.setOwnerType(OwnerTypeEnum.SHOP.code());
        shopLog.setOrderId(orderInfo.getOrderId());
        shopLog.setDevId(delivery.getId());
        shopLog.setIoType(IOTypeEnum.IN.code());
        shopLog.setAmountType(AmountTypeEnum.UNSETTLED_AMOUNT.code());
        shopLog.setChangeAmount(shopGetAmount);
        shopLog.setReason(ShopWalletChangeReason.PAY.value());
        // 商家优惠券/补贴 平台优惠券/补贴  后期增加的话需要加入
        shopLog.setUserAmount(orderInfo.getOrderAmount());
        shopLog.setPlatformCommission(platformShopAmount);
//        shopLog.setTotalAmount(orderInfo.getGoodsAmount());
        shopLog.setTotalAmount(orderInfo.getOrderAmount());
        int shopCount = platformWalletLogMapper.insert(shopLog);

        // 商家冻结金额
        ShopWallet shopWallet = shopWalletMapper.selectById(orderInfo.getTenantId());
        double newShopGetAmount = Arith.add(shopWallet.getFreezeAmount(), shopGetAmount);
        shopWallet.setFreezeAmount(newShopGetAmount);
        shopWalletMapper.updateById(shopWallet);

        return riderCount + shopCount > 0;
    }

    @Override
    public Long getSettledCount(String orderId, Integer ownerType) {
        // 查询该订单是否有已结算记录
        LambdaQueryWrapper<PlatformWalletLog> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(PlatformWalletLog::getOrderId,orderId)
                .eq(PlatformWalletLog::getReason, ShopWalletChangeReason.SETTLED.value())
                .eq(PlatformWalletLog::getOwnerType, ownerType);
        long count = platformWalletLogMapper.selectCount(queryWrapper);
        return count;
    }

    @Override
    public List<PlatformWalletLog> getLogByOrderId(String orderId, Integer ownerType) {
        // 查询该订单的待结算记录
        LambdaQueryWrapper<PlatformWalletLog> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(PlatformWalletLog::getOrderId,orderId)
                .eq(PlatformWalletLog::getOwnerType, ownerType);
        List<PlatformWalletLog> list = platformWalletLogMapper.selectList(queryWrapper);
        return list;
    }

    @Override
    public Boolean unfreezingAmount(String orderId) {
        OrderInfo orderInfo = orderInfoMapper.selectById(orderId);
        OrderDelivery delivery = deliveryMapper.selectById(orderInfo.getDeliveryId());

        // 骑手金额解冻，解冻的金额变化记录应该不用记录历史吧？目前没有记录。
        RiderWallet riderWallet = riderWalletMapper.selectById(delivery.getRiderId());
        PlatformWalletLog riderLog = getLogList(orderId, OwnerTypeEnum.RIDER.code(), delivery.getRiderId());
        if(ObjectUtils.isNotEmpty(riderLog)){
            // 解冻这部分金额
            double freezeAmount = Arith.sub(riderWallet.getFreezeAmount(), riderLog.getChangeAmount());
            riderWallet.setFreezeAmount(freezeAmount);
            // 待结算增加这部分金额
            double unsettledAmount = Arith.add(riderWallet.getUnsettledAmount(), riderLog.getChangeAmount());
            riderWallet.setUnsettledAmount(unsettledAmount);
            riderWalletMapper.updateById(riderWallet);
        }


        // 商家金额解冻
        ShopWallet shopWallet = shopWalletMapper.selectById(orderInfo.getTenantId());
        PlatformWalletLog shopLog = getLogList(orderId, OwnerTypeEnum.SHOP.code(),orderInfo.getTenantId());
        // 解冻这部分金额
        double freezeAmount = Arith.sub(shopWallet.getFreezeAmount(), shopLog.getChangeAmount());
        shopWallet.setFreezeAmount(freezeAmount);
        // 待结算增加这部分金额
        double unsettledAmount = Arith.add(shopWallet.getUnsettledAmount(), shopLog.getChangeAmount());
        shopWallet.setUnsettledAmount(unsettledAmount);
        int count = shopWalletMapper.updateById(shopWallet);
        return count > 0;
    }

    @Override
    public IPage<PlatformWalletLog> page(PlatformWalletLogPageBO pageBO) {
        Page<PlatformWalletLog> page = Page.of(pageBO.getCurrent(), pageBO.getSize());
        LambdaQueryWrapper<PlatformWalletLog> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.orderByDesc(PlatformWalletLog::getCreateTime);
        IPage<PlatformWalletLog> pageResult = platformWalletLogMapper.selectPage(page, queryWrapper);
        return pageResult;
    }


    /**
     * 查询入账记录
     * @param orderId
     * @param ownerType
     * @param ownerId
     * @return
     */
    private PlatformWalletLog getLogList(String orderId,Integer ownerType,Long ownerId){

        LambdaQueryWrapper<PlatformWalletLog> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(PlatformWalletLog::getOrderId,orderId)
                .eq(PlatformWalletLog::getOwnerType,ownerType)
                .eq(PlatformWalletLog::getOwnerId,ownerId)
                .eq(PlatformWalletLog::getReason,ShopWalletChangeReason.PAY.value());
        List<PlatformWalletLog> list = platformWalletLogMapper.selectList(queryWrapper);
        if(list.size() > 0){
            return list.get(0);
        }
        return null;
    }
}
